/**
 * 端口检测工具模块
 */

const net = require('net');
const logger = require('./logger');

/**
 * 检查端口是否被占用
 * @param {number} port - 要检查的端口号
 * @param {string} host - 主机地址，默认为localhost
 * @returns {Promise<boolean>} 端口是否被占用
 */
exports.isPortInUse = (port, host = 'localhost') => {
  return new Promise((resolve) => {
    const server = net.createServer();
    
    server.once('error', (err) => {
      // 如果是地址已在使用错误，则端口被占用
      resolve(err.code === 'EADDRINUSE' || err.code === 'EACCES');
    });
    
    server.once('listening', () => {
      // 端口可用，关闭服务器
      server.close(() => {
        resolve(false);
      });
    });
    
    server.listen(port, host);
  });
};

/**
 * 查找可用的端口
 * @param {number} startPort - 起始端口
 * @param {number} maxAttempts - 最大尝试次数
 * @param {string} host - 主机地址
 * @returns {Promise<number|null>} 找到的可用端口或null
 */
exports.findAvailablePort = async (startPort, maxAttempts = 10, host = 'localhost') => {
  for (let i = 0; i < maxAttempts; i++) {
    const port = startPort + i;
    const isInUse = await exports.isPortInUse(port, host);
    
    if (!isInUse) {
      logger.debug(`找到可用端口: ${port}`);
      return port;
    }
    
    logger.debug(`端口 ${port} 已被占用，尝试下一个端口`);
  }
  
  logger.warn(`在 ${startPort} 到 ${startPort + maxAttempts - 1} 范围内未找到可用端口`);
  return null;
};

/**
 * 等待端口可用
 * @param {number} port - 端口号
 * @param {number} timeout - 超时时间（毫秒）
 * @param {number} interval - 检查间隔（毫秒）
 * @returns {Promise<boolean>} 是否在超时前可用
 */
exports.waitForPort = async (port, timeout = 30000, interval = 500) => {
  const startTime = Date.now();
  
  while (Date.now() - startTime < timeout) {
    const isInUse = await exports.isPortInUse(port);
    
    if (isInUse) {
      logger.debug(`端口 ${port} 已可用`);
      return true;
    }
    
    logger.debug(`等待端口 ${port} 可用...`);
    await new Promise(resolve => setTimeout(resolve, interval));
  }
  
  logger.warn(`等待端口 ${port} 超时（${timeout}ms）`);
  return false;
};

/**
 * 终止占用指定端口的进程
 * 注意：此功能在不同平台上的实现可能需要调整
 * @param {number} port - 端口号
 * @returns {Promise<boolean>} 是否成功终止
 */
exports.killProcessOnPort = async (port) => {
  const { exec } = require('child_process');
  const os = require('os');
  
  return new Promise((resolve) => {
    let command;
    
    if (os.platform() === 'win32') {
      // Windows平台
      command = `netstat -ano | findstr :${port}`;
    } else {
      // Linux/Mac平台
      command = `lsof -i :${port} -t`;
    }
    
    exec(command, (error, stdout) => {
      if (error) {
        logger.debug(`查找端口 ${port} 的进程失败: ${error.message}`);
        resolve(false);
        return;
      }
      
      if (!stdout.trim()) {
        logger.debug(`端口 ${port} 上没有找到进程`);
        resolve(false);
        return;
      }
      
      let pids;
      if (os.platform() === 'win32') {
        // Windows输出格式不同，需要解析
        pids = stdout.trim().split('\n')
          .map(line => line.trim().split(/\s+/).pop())
          .filter(pid => pid && !isNaN(pid));
      } else {
        pids = stdout.trim().split('\n');
      }
      
      logger.debug(`找到占用端口 ${port} 的进程: ${pids.join(', ')}`);
      
      // 终止进程
      const killPromises = pids.map(pid => {
        return new Promise((killResolve) => {
          const killCommand = os.platform() === 'win32' ? `taskkill /F /PID ${pid}` : `kill ${pid}`;
          
          exec(killCommand, (killError) => {
            if (killError) {
              logger.error(`终止进程 ${pid} 失败: ${killError.message}`);
              killResolve(false);
            } else {
              logger.debug(`成功终止进程 ${pid}`);
              killResolve(true);
            }
          });
        });
      });
      
      Promise.all(killPromises).then(results => {
        resolve(results.some(result => result));
      });
    });
  });
};